home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 3
/
Cream of the Crop 3.iso
/
comm
/
wnos5src.zip
/
DIRUTIL.C
< prev
next >
Wrap
Text File
|
1993-08-09
|
8KB
|
386 lines
/* dirutil.c - MS-DOS directory reading routines
*
* Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
* Directory sorting by Mike Chepponis, K3MC
* New version using regs.h by Russell Nelson.
* Rewritten for Turbo-C 2.0 routines by Phil Karn, KA9Q 25 March 89
*
* Changed commas to dots for European use :-) - DB3FL.910216
*
*/
#include <stdio.h>
#include <dir.h>
#include <dos.h>
#include <stdlib.h>
#include <ctype.h>
#include "global.h"
#include "dirutil.h"
#include "commands.h"
#include "files.h"
#ifdef XXX
static int getdir_nosort __ARGS((char *path,int full,FILE *file));
#endif
#define REGFILE (FA_HIDDEN|FA_SYSTEM|FA_DIREC)
#define insert_ptr(list,new) (new->next = list,list = new)
struct dirsort {
struct dirsort *next;
struct ffblk de;
};
#define NULLSORT (struct dirsort *)0
/*
* Return a string with commas every 3 positions.
* the original string is replace with the string with commas.
* The caller must be sure that there is enough room for the resultant
* string.
*
* k3mc 4 Dec 87
*
* Changed to dots instead of commas for european use - DB3FL.910216
*
*/
static void near
commas(char *dest)
{
unsigned cc = (strlen(dest) - 1) % 3 + 1; /* Tells us when to insert a comma */
/* Make a copy, so we can muck around */
char *core = strxdup(dest);
char *src = core;
while(*src != '\0'){
*dest++ = *src++;
if( ((--cc) == 0) && *src ) {
*dest++ = '.';
cc = 3;
}
}
xfree(core);
*dest = '\0';
}
static int near
fncmp(char *a,char *b)
{
int i;
for(;;){
if (*a == '.') {
return -1;
}
if (*b == '.') {
return 1;
}
if ((i = *a - *b++) != 0) {
return i;
}
if (!*a++) {
return -1;
}
}
}
/* Provide additional information only on DIR */
static void near
print_free_space(FILE *file,int n,int d)
{
unsigned long free_bytes = 0, total_bytes = 0, bpcl = 0;
char s_free[15], s_total[15];
struct dfree dtable;
memset(&dtable,0,sizeof(struct dfree));
/* Find disk free space */
getdfree(d,&dtable);
bpcl = dtable.df_bsec * dtable.df_sclus;
free_bytes = dtable.df_avail * bpcl;
total_bytes = dtable.df_total * bpcl;
sprintf(s_free,"%ld",free_bytes);
commas(s_free);
sprintf(s_total,"%ld",total_bytes);
commas(s_total);
fprintf(file,"%s%d file(s). %s bytes free. Disk size %s bytes.\n",
(n & 1) ? "\n" : "",n,s_free,s_total);
}
static void near
format_fname_full(FILE *file,struct ffblk *sbuf,int full,int n)
{
char line_buf[50]; /* for long dirlist */
char cbuf[20]; /* for making line_buf */
strcpy(cbuf,sbuf->ff_name);
if (sbuf->ff_attrib & FA_DIREC) {
strcat(cbuf, "/");
}
if (full) {
/* Long form, give other info too */
sprintf(line_buf,"%-13s",cbuf);
if(sbuf->ff_attrib & FA_DIREC) {
strcat(line_buf," ");/* 11 spaces */
} else {
sprintf(cbuf,"%ld",sbuf->ff_fsize);
commas(cbuf);
sprintf(line_buf+strlen(line_buf),"%10s ",cbuf);
}
sprintf(line_buf+strlen(line_buf),"%2d:%02d %2d.%02d.%02d%s",
(sbuf->ff_ftime >> 11) & 0x1f, /* hour */
(sbuf->ff_ftime >> 5) & 0x3f, /* minute */
(sbuf->ff_fdate ) & 0x1f, /* day */
(sbuf->ff_fdate >> 5) & 0xf, /* month */
(sbuf->ff_fdate >> 9) + 80, /* year */
(n & 1) ? " " : "\n");
fputs(line_buf,file);
} else {
fprintf(file,"%s\n",cbuf);
}
}
/* find the first or next file and lowercase it. */
static int near
nextname(int command, char *name, struct ffblk *sbuf)
{
int found = (command == 0) ? findfirst(name,sbuf,REGFILE) : findnext(sbuf);
if((found = found == 0) != 0) {
strlwr(sbuf->ff_name);
}
return found;
}
/* fix up the filename so that it contains the proper wildcard set */
static char * near
wildcardize(char *path)
{
struct ffblk sbuf;
char ourpath[64];
/* Root directory is a special case */
if(path == NULLCHAR) {
path = "/*.*";
} else {
int i = strlen(path) - 1;
if(path[i] == '\\' || path[i] == '/') {
strcat(path,"*.*");
} else if(path[i] == ':') {
strcat(path,"/*.*");
}
}
/* if they gave the name of a subdirectory, append \*.* to it */
if(nextname(0, path, &sbuf)
&& (sbuf.ff_attrib & FA_DIREC)
&& !nextname(1, path, &sbuf)) {
/* if there isn't enough room, give up -- it's invalid anyway */
if(strlen(path) + 4 > 63) {
return path;
}
strcpy(ourpath, path);
strcat(ourpath, "\\*.*");
return ourpath;
}
return path;
}
/* Create a directory listing in a temp file and return the resulting file
* descriptor. If full == 1, give a full listing; else return just a list
* of names.
*/
FILE *
dir(char *path,int full)
{
FILE *fp;
if((fp = Tmpfile(0,1)) != NULLFILE) {
getdir(path,full,fp);
rewind(fp);
}
return fp;
}
/* wildcard filename lookup */
int
filedir(char *name,int times,char *ret_str)
{
static struct ffblk sbuf;
int rval = (times == 0) ? findfirst(name,&sbuf,REGFILE) : findnext(&sbuf);
if(rval == -1) {
*ret_str = '\0';
} else {
strcpy(ret_str,sbuf.ff_name);
}
return rval;
}
/* do a directory list to the stream full = 0 -> short form, 1 is long */
int
getdir(char *path,int full,FILE *file)
{
struct ffblk sbuf;
int command = 0, n = 0, d = 0;
struct dirsort *head = NULLSORT, *here, *new, *next, *this;
path = wildcardize(path);
for(;;){
if(!nextname(command,path,&sbuf)) {
break;
}
/* Got first one already... */
command = 1;
if(sbuf.ff_name[0] == '.') {
/* drop "." and ".." */
continue;
}
new = mxallocw(sizeof(struct dirsort));
/* Copy contents of directory entry struct */
new->de = sbuf;
/* insert it into the list */
if(!head || fncmp(new->de.ff_name,head->de.ff_name) < 0) {
insert_ptr(head,new);
} else {
for(this = head; this->next != NULLSORT; this = this->next) {
if(fncmp(new->de.ff_name, this->next->de.ff_name) < 0) {
break;
}
}
insert_ptr(this->next,new);
}
} /* infinite FOR loop */
for (here = head; here; here = here->next) {
format_fname_full(file,&here->de,full,++n);
}
/* Give back all the memory we temporarily needed... */
for( ; head != NULLSORT; head = next) {
next = head->next;
xfree(head);
}
if(path[1] == ':') {
d = (toupper(*path)) - 64;
}
if(full) {
print_free_space(file,n,d);
}
return 0;
}
/* Change working directory */
int
docd(int argc,char **argv,void *p)
{
char dirname[MAXPATH], *s;
if(argc < 2) {
if(getcwd(dirname,MAXPATH) != NULLCHAR) {
while((s = strchr(dirname,'\\')) != NULLCHAR)
*s = '/';
tprintf("%s\n",dirname);
}
} else if(chdir(argv[1]) == -1) {
tprintf("Can't change to %s: %s\n",argv[1],sys_errlist[errno]);
}
return 0;
}
/* List directory to console */
int
dodir(int argc,char **argv,void *p)
{
FILE *fp;
char *margv[2];
margv[1] = strxdup(__tmpnam(NULL,0));
if((fp = Fopen(margv[1],WRITE_TEXT,0,1)) != NULLFILE) {
char *path = (argc < 2) ? "*.*" : argv[1];
getdir(path,1,fp);
Fclose(fp);
domore(2,margv,p);
unlink(margv[1]);
}
xfree(margv[1]);
return 0;
}
/* Delete file */
int
dodelete(int argc,char **argv,void *p)
{
if(unlink(argv[1]) == -1) {
tprintf("Can't delete %s: %s\n",argv[1],sys_errlist[errno]);
}
return 0;
}
/* Rename file */
int
dorename(int argc,char **argv,void *p)
{
if(rename(argv[1],argv[2]) == -1) {
tprintf("Can't rename %s to %s: %s\n",argv[1],argv[2],sys_errlist[errno]);
}
return 0;
}
/* Create directory */
int
domkd(int argc,char **argv,void *p)
{
if(mkdir(argv[1]) == -1) {
tprintf("Can't make %s: %s\n",argv[1],sys_errlist[errno]);
}
return 0;
}
/* Remove directory */
int
dormd(int argc,char **argv,void *p)
{
if(rmdir(argv[1]) == -1) {
tprintf("Can't delete %s: %s\n",argv[1],sys_errlist[errno]);
}
return 0;
}
#ifdef XXX
static int
getdir_nosort(path,full,file)
char *path;
int full;
FILE *file;
{
struct ffblk sbuf;
int command = 0, n = 0; /* Number of directory entries */
path = wildcardize(path);
while(nextname(command, path, &sbuf)){
command = 1; /* Got first one already... */
if (sbuf.ff_name[0] == '.') /* drop "." and ".." */
continue;
format_fname_full(file, &sbuf, full, ++n);
}
if(full)
print_free_space(file, n, 0);
return 0;
}
#endif